package org.fireking.myapplication.drawing.impl

import android.graphics.Canvas
import android.graphics.Paint
import android.util.Log
import com.github.mikephil.charting.utils.Transformer
import org.fireking.myapplication.ChartDrawingRenderer
import org.fireking.myapplication.drawing.ShapeDrawingStrategy

class LineDrawingStrategy(
    var startX: Float,
    var startY: Float,
    var endX: Float,
    var endY: Float
) : ShapeDrawingStrategy {

    override fun draw(canvas: Canvas, transformer: Transformer?, paint: Paint) {
        transformer ?: return
        val startPoints = floatArrayOf(startX, startY)
        val endPoints = floatArrayOf(endX, endY)
        transformer.pointValuesToPixel(startPoints)
        transformer.pointValuesToPixel(endPoints)
        canvas.drawLine(
            startPoints[0], startPoints[1], endPoints[0], endPoints[1], paint
        )
    }

    override fun containsPoint(x: Float, y: Float, touchTolerance: Float): Boolean {
        val a = x - startX
        val b = y - startY
        val c = endX - startX
        val d = endY - startY
        val dot = a * c + b * d
        val lenSq = c * c + d * d
        var param = -1f
        if (lenSq != 0f) param = dot / lenSq
        var xx: Float
        var yy: Float
        if (param < 0f) {
            xx = startX
            yy = startY
        } else if (param > 1f) {
            xx = endX
            yy = endY
        } else {
            xx = startX + param * c
            yy = startY + param * d
        }
        val dx = x - xx
        val dy = y - yy
        val distance = Math.sqrt((dx * dx + dy * dy).toDouble()).toFloat()
        return distance <= touchTolerance
    }

    override fun containsPointInside(x: Float, y: Float, edgeTolerance: Float): Boolean {
        val a = x - startX
        val b = y - startY
        val c = endX - startX
        val d = endY - startY
        val dot = a * c + b * d
        val lenSq = c * c + d * d
        if (lenSq == 0f) return false
        val param = dot / lenSq
        if (param >= 0.33f && param <= 0.67f) {
            val xx = startX + param * c
            val yy = startY + param * d
            val dx = x - xx
            val dy = y - yy
            val distance = Math.sqrt((dx * dx + dy * dy).toDouble()).toFloat()
            val isInside = distance <= edgeTolerance
            Log.d(
                "LineDrawingStrategy",
                "Inside check: param=$param, distance=$distance, result=$isInside"
            )
            return isInside
        }
        Log.d("LineDrawingStrategy", "Not in middle segment: param=$param")
        return false
    }

    override fun getControlPoints(): List<ChartDrawingRenderer.ControlPoint> {
        return listOf(
            ChartDrawingRenderer.ControlPoint(
                0,
                startX,
                startY,
                ChartDrawingRenderer.ControlPointType.START
            ),
            ChartDrawingRenderer.ControlPoint(
                1,
                endX,
                endY,
                ChartDrawingRenderer.ControlPointType.END
            )
        )
    }

    override fun applyControlPointMove(controlPointId: Int, deltaX: Float, deltaY: Float) {
        when (controlPointId) {
            0 -> {
                startX += deltaX
                startY += deltaY
            }
            1 -> {
                endX += deltaX
                endY += deltaY
            }
        }
    }

    override fun move(deltaX: Float, deltaY: Float) {
        startX += deltaX
        startY += deltaY
        endX += deltaX
        endY += deltaY
    }
}